package managers.dateManager.endFrozen.effortChange;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit.framework.TestCase;

import org.apache.log4j.Logger;
import org.tbjd.client.beans.Task;
import org.tbjd.client.constants.NotificationsConstants;
import org.tbjd.client.exceptions.DateManagerException;
import org.tbjd.client.managers.TaskManager;
import org.tbjd.client.states.StateEndFrozenASAP;

import factories.TaskFactory;

/**
 * <p>
 * Test TaskManager's methods
 * </p>
 * <p>
 * <b>Case</b>
 * </p>
 * <p>
 * A task with 2 successors and everyone in ASAP ChainingMode
 * </p>
 * <p>
 * <b>Action</b>
 * </p>
 * <p>
 * Effort of task "task" is changed
 * </p>
 * <p>
 * Expected
 * <ul>
 * <li>update BeginDate of "task"</li>
 * <li>switch chaining mode of "task" to manual</li>
 * </ul>
 * </p>
 * 
 * @author Michael Martin
 * @author Antonio Carrozzini
 * @version 1.0
 * 
 */
public class EndFrozen_EffortChange_Successors_Basic extends TestCase {

	/*
	 * Task		Begins 		Ends 		Successor 	ChainingMode	task duration + 24 hours
	 * task 	13.6.2009 	14.6.2009 	s1, s2	 	ASAP 			12.6.2009 - 14.6.2009
	 * s1		15.6.2009 	17.6.2009 	-			ASAP 			15.6.2009 - 17.6.2009
	 * s2		18.6.2009 	21.6.2009 	-			ASAP 			18.6.2009 - 21.6.2009
	 */

	private Map<Integer, Object> map = null;
	private Logger log = Logger.getLogger("console");
	private DateFormat df = DateFormat.getInstance();
	private Task task = null;
	private TaskManager dateManager = new TaskManager();

	protected void setUp() throws Exception {
		df = new SimpleDateFormat("dd.MM.yyyy");

		this.task = TaskFactory.getInstance();
		this.task.setName("task");
		this.task.setBeginDate(df.parse("11.6.2009"));
		this.task.setEndDate(df.parse("14.6.2009"));
		this.task.setDuration(72f);
		this.task.setEffort(72f);
		this.task.setState(new StateEndFrozenASAP(this.task.getState().getDurationModeState()));

		Task s1 = TaskFactory.getInstance();
		s1.setName("s1");
		s1.setBeginDate(df.parse("15.6.2009"));
		s1.setEndDate(df.parse("17.6.2009"));
		s1.setDuration(48f);
		s1.setEffort(48f);
		
		Task s2 = TaskFactory.getInstance();
		s2.setName("s2");
		s2.setBeginDate(df.parse("18.6.2009"));
		s2.setEndDate(df.parse("21.6.2009"));
		s2.setDuration(72f);
		s2.setEffort(72f);

		this.task.addSuccessor(s1);
		this.task.addSuccessor(s2);

		super.setUp();
	}

	public void testListNullity() {
		System.out.println("");
		log.debug(" === testListNullity");

		float newEffort = 96f;
		log.debug("new effort = " + newEffort);

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.TASKMANAGER_ACTION_effort, newEffort);
		this.map.put(NotificationsConstants.TASKMANAGER_BEAN, this.task);
		this.map.put(NotificationsConstants.TASKMANAGER_SENDER, null);

		log.debug("call TaskManager...");
		try {
			assertNotNull("Updated bean list isn't null", dateManager.manageDates(map));

		} catch (DateManagerException e) {
			fail(e.getMessage());

		}

	}

	public void testListSize() {
		System.out.println("");
		log.debug(" === testListSize");

		float newEffort = 96f;
		log.debug("new effort = " + newEffort);

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.TASKMANAGER_ACTION_effort, newEffort);
		this.map.put(NotificationsConstants.TASKMANAGER_BEAN, this.task);
		this.map.put(NotificationsConstants.TASKMANAGER_SENDER, null);

		log.debug("call dateManager...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager.manageDates(this.map);

		} catch (DateManagerException e) {
			fail(e.getMessage());

		}
		assertEquals(1, updatedBeans.size());

	}

	public void testDates() {
		System.out.println("");
		log.debug(" === testDates");

		float newEffort = 48f;
		log.debug("new effort = " + newEffort);

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.TASKMANAGER_ACTION_effort, newEffort);
		this.map.put(NotificationsConstants.TASKMANAGER_BEAN, this.task);
		this.map.put(NotificationsConstants.TASKMANAGER_SENDER, null);

		log.debug("call dateManager...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager.manageDates(this.map);

		} catch (DateManagerException e) {
			fail(e.getMessage());

		}

		for (Task updatedBean : updatedBeans) {
			log.debug(updatedBean.getName() + " \t updated with BeginDate = " + df.format(updatedBean.getBeginDate()) + " , EndDate = "
					+ df.format(updatedBean.getEndDate()));
			try {
				if (updatedBean.getName().equalsIgnoreCase("task")) {
					assertEquals(df.parseObject("12.6.2009"), updatedBean.getBeginDate());
					assertEquals(df.parseObject("14.6.2009"), updatedBean.getEndDate());
				}
				if (updatedBean.getName().equalsIgnoreCase("s1")) {
					fail();
				}
				if (updatedBean.getName().equalsIgnoreCase("s2")) {
					fail();
				}

			} catch (ParseException e) {
				fail(e.getMessage());

			}
		}
	}

	public void testChainingModes() {
		System.out.println("");
		log.debug(" === testChainingModes");

		float newEffort = 48f;
		log.debug("new effort = " + newEffort);

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.TASKMANAGER_ACTION_effort, newEffort);
		this.map.put(NotificationsConstants.TASKMANAGER_BEAN, this.task);
		this.map.put(NotificationsConstants.TASKMANAGER_SENDER, null);

		log.debug("call dateManager...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager.manageDates(this.map);

		} catch (DateManagerException e) {
			fail(e.getMessage());

		}

		for (Task updatedBean : updatedBeans) {
			log.debug(updatedBean.getName() + " \t updated with BeginDate = " + df.format(updatedBean.getBeginDate()) + " , EndDate = "
					+ df.format(updatedBean.getEndDate()));
			if (updatedBean.getName().equalsIgnoreCase("task")) {
				assertFalse(updatedBean.getState().isASAPChainingMode());
			}
			if (updatedBean.getName().equalsIgnoreCase("s1")) {
				fail();
			}
			if (updatedBean.getName().equalsIgnoreCase("s2")) {
				fail();
			}

		}

	}

	public void testDurations() {
		System.out.println("");
		log.debug(" === testDurations");

		float newEffort = 48f;
		log.debug("new effort = " + newEffort);

		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.TASKMANAGER_ACTION_effort, newEffort);
		this.map.put(NotificationsConstants.TASKMANAGER_BEAN, this.task);
		this.map.put(NotificationsConstants.TASKMANAGER_SENDER, null);

		log.debug("call dateManager...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager .manageDates(this.map);

		} catch (DateManagerException e) {
			fail(e.getMessage());

		}

		for (Task updatedBean : updatedBeans) {
			log.debug(updatedBean.getName() + " \t updated with BeginDate = " + df.format(updatedBean.getBeginDate()) + " , EndDate = "
					+ df.format(updatedBean.getEndDate()));
			if (updatedBean.getName().equalsIgnoreCase("task")) {
				assertEquals(48f, updatedBean.getDuration());
			}
			if (updatedBean.getName().equalsIgnoreCase("s1")) {
				fail();
			}
			if (updatedBean.getName().equalsIgnoreCase("s2")) {
				fail();
			}

		}

	}
	
	public void testEfforts() {
		System.out.println("");
		log.debug(" === testEfforts");
		
		float newEffort = 48f;
		log.debug("new effort = " + newEffort);
		
		this.map = new HashMap<Integer, Object>();
		this.map.put(NotificationsConstants.TASKMANAGER_ACTION_effort, newEffort);
		this.map.put(NotificationsConstants.TASKMANAGER_BEAN, this.task);
		this.map.put(NotificationsConstants.TASKMANAGER_SENDER, null);
		
		log.debug("call dateManager...");
		List<Task> updatedBeans = null;
		try {
			updatedBeans = dateManager .manageDates(this.map);
			
		} catch (DateManagerException e) {
			fail(e.getMessage());
			
		}
		
		for (Task updatedBean : updatedBeans) {
			log.debug(updatedBean.getName() + " \t updated with BeginDate = " + df.format(updatedBean.getBeginDate()) + " , EndDate = "
					+ df.format(updatedBean.getEndDate()));
			if (updatedBean.getName().equalsIgnoreCase("task")) {
				assertEquals(48f, updatedBean.getDuration());
			}
			if (updatedBean.getName().equalsIgnoreCase("s1")) {
				fail();
			}
			if (updatedBean.getName().equalsIgnoreCase("s2")) {
				fail();
			}
			
		}
		
	}
}